<?php
/**
 * WarehouseRepo.php
 *
 * @copyright   2023 thingsworld.com.cn - All Rights Reserved
 * @link        http://thingsworld.com.cn/
 * @author      stiffer.chen <chenl@thingsworld.com.cn>
 * @created     2023-05-11 16:02:10
 * @modified    2023-05-11 16:02:10
 *
 */

namespace App\Repositories;

use App\Http\Resources\WarehouseResource;
use App\Models\DeptModel;
use App\Models\UserModel;
use App\Models\Warehouse;

class WarehouseRepo
{
    public static function getList()
    {
        $perPage = (int)request('limit');
        if ($perPage < 1) {
            $perPage = 10;
        }
        $isManager = intval(request('is_manager', 0));
        $builder = Warehouse::query();
        if ($isManager) {
            $builder->join('warehouse_user as wu', 'wu.warehouse_id', '=', 'warehouse.id')
                ->where('wu.user_id', '=', registry('user_id'));
        }
        $name = trim(request('name', ''));
        if ($name) {
            $builder->where('warehouse.name', 'like', "%{$name}%");
        }
        $builder->select(['warehouse.*']);
        $builder->with(['depts.dept', 'users.user']);
        $builder->orderByDesc('update_time');
        $warehouses = $builder->paginate($perPage);
        $warehouses->transform(function ($item) {
            return new WarehouseResource($item);
        });
        return $warehouses;
    }

    // 存储仓库
    public static function store(int $id = 0)
    {
        $data = self::requestData($id);

        $warehouseData = $data['main'];
        $deptIds = $data['dept_ids'];
        $userIds = $data['user_ids'];

        $warehouse = Warehouse::find($id);
        if (empty($warehouse)) {
            $warehouse = new Warehouse();
        }

        $depts = [];
        foreach ($deptIds as $deptId) {
            $depts[] = new Warehouse\Dept([
                'dept_id' => $deptId
            ]);
        }

        $users = [];
        foreach ($userIds as $userId) {
            $users[] = new Warehouse\User([
                'user_id' => $userId
            ]);
        }

        $warehouse->depts()->delete();
        $warehouse->users()->delete();

        $warehouse->fill($warehouseData);
        $warehouse->saveOrFail();

        $warehouse->depts()->saveMany($depts);
        $warehouse->users()->saveMany($users);

        return self::fetch($warehouse->id);
    }

    public static function fetch($id)
    {
        $warehouse = Warehouse::with(['depts.dept', 'users.user'])->find($id);
        return (new WarehouseResource($warehouse));
    }

    // 获取所有仓库管理员ID
    public static function managerIds()
    {
        return Warehouse\User::query()->distinct()->select(['user_id'])->pluck('user_id')->all();
    }

    // 当前用户能管理的仓库ID
    public static function userWarehouseIds($userId)
    {
        $builder = Warehouse::query()
            ->from('warehouse as w')
            ->join('warehouse_user as wu', 'w.id', '=', 'wu.warehouse_id')
            ->select(['w.id'])
            ->where('wu.user_id', '=', $userId);
        return $builder->get()->pluck('id')->toArray();
    }

    // 解析数据
    private static function requestData($id)
    {
        $warehouseData = request()->getContent();
        $warehouseArr = json_decode($warehouseData, true);

        if ($id) {
            $primaryWarehouse = Warehouse::find($id);
            if (empty($primaryWarehouse)) {
                throw new \Exception("仓库不存在(#{$id})");
            }
        }

        // validate data
        $name = trim($warehouseArr['name'] ?? '');
        if (!$name) {
            throw new \Exception('请输入仓库名称');
        }
        $nameWarehouse = Warehouse::byName($name)->first();
        if (!empty($nameWarehouse)) {
            if (!$id && $nameWarehouse) {
                throw new \Exception('仓库名称已被使用');
            }
            if ($id && $nameWarehouse->id != $id) {
                throw new \Exception('仓库名称已被使用');
            }
        }

        $provinceId = intval($warehouseArr['province_id'] ?? 0);
        $cityId = intval($warehouseArr['city_id'] ?? 0);
        $countyId = intval($warehouseArr['county_id'] ?? 0);
        $zones = get_zones($provinceId, $cityId, $countyId);

        $address = trim($warehouseArr['address'] ?? '');
        if (!$address) {
            throw new \Exception('请输入详细地址');
        }

        $deptIds = $warehouseArr['dept_ids'] ?? [];
        if (empty($deptIds)) {
            // throw new \Exception('选择仓库部门');
        }
        $warehouseDeptIds = [];
        foreach ($deptIds as $deptId) {
            $itemDept = DeptModel::query()->where('id', $deptId)->first();
            if (empty($itemDept)) {
                throw new \Exception("区域不存在(#{$deptId})");
            }
            $warehouseDeptIds[] = $deptId;
        }

        $userIds = $warehouseArr['user_ids'] ?? [];
        if (empty($userIds)) {
            throw new \Exception('选择仓库管理员');
        }
        $warehouseUserIds = [];
        foreach ($userIds as $userId) {
            $user = UserModel::find($userId);
            if (empty($user)) {
                throw new \Exception("管理员账号不存在(#{$userId})");
            }
            $warehouseUserIds[] = $userId;
        }

        $number = self::generateNumber($id);

        $main = [
            'name' => $name,
            'w_number' => $number,
            'province_id' => $zones['province_id'],
            'province_name' => $zones['province_name'],
            'city_id' => $zones['city_id'],
            'city_name' => $zones['city_name'],
            'county_id' => $zones['county_id'],
            'county_name' => $zones['county_name'],
            'address' => $address,
            'create_user_id' => registry('user_id'),
        ];
        return [
            'main' => $main,
            'dept_ids' => $deptIds,
            'user_ids' => $userIds
        ];
    }

    private static function generateNumber($id)
    {
        $warehouse = Warehouse::find($id);
        if (!empty($warehouse)) {
            return $warehouse->w_number;
        }
        $number = 'WA' . date('Ymd') . rand(10000, 99999);
        $numberWarehouse = Warehouse::byNumber($number)->first();
        if (empty($numberWarehouse)) {
            return $number;
        }
        return self::generateNumber($id);
    }
}